package handler

import (
	"github.com/gin-gonic/gin"
	"github.com/lab-online/internal/user/constant"
	"github.com/lab-online/internal/user/entity"
	"github.com/lab-online/pkg/auth"
	mw "github.com/lab-online/pkg/middleware"
	"github.com/lab-online/pkg/resp"
)

type UpdateUserReqBody struct {
	Name string `json:"name" example:"杏鸣"`
	Role uint8  `json:"role" example:"1"`
}

type UpdateUserReqParams struct {
	Username string `uri:"id" binding:"required" example:"20240126"` // 学号或者工号
}

var UpdateUserValidator = mw.NewValidator(func() *mw.ValidatorOptions {
	return &mw.ValidatorOptions{
		Body:   &UpdateUserReqBody{},
		Params: &UpdateUserReqParams{},
	}
})

type updateUserRespBodyData struct {
	Username string `json:"username" binding:"required" example:"20240126"`
	Name     string `json:"name" binding:"required" example:"杏鸣"`
	Role     uint8  `json:"role" binding:"required" example:"1"`
}
type UpdateUserRespBody struct {
	resp.BaseRespBody
	Data updateUserRespBodyData `json:"data" binding:"required"`
}

type UpdateUserFailedRespBody struct {
	resp.BaseRespBody
	Err string `json:"err"  binding:"required" example:"错误信息"`
}

// UpdateUser
//
//	@Summary				修改个人信息/修改用户信息(管理员)
//	@Description.markdown	UpdateUser
//	@Tags					user
//	@Accept					json
//	@Produce				json
//	@Param					Authorization	header		string				true	"Bearer Token"
//	@Param					id				path		string				true	"学号或者工号"
//	@Param					Body			body		UpdateUserReqBody	true	"JSON 请求体"
//	@Success				200				{object}	UpdateUserRespBody
//	@Failure				400				{object}	UpdateUserFailedRespBody
//	@Security				bearer
//	@x-apifox-status		"testing"
//	@Router					/v1/users/:id  [put]
func (h *Handler) UpdateUser(c *gin.Context) {
	authEntity := c.MustGet(auth.KeyAuth).(auth.AuthEntity)
	body := c.MustGet(mw.KeyBody).(*UpdateUserReqBody)
	params := c.MustGet(mw.KeyParams).(*UpdateUserReqParams)

	userEntity := entity.NewUserEntity(
		entity.WithUsername(params.Username),
		entity.WithName(body.Name),
		entity.WithRole(body.Role),
	)

	if user, err := h.domain.UpdateUser(authEntity, userEntity); err != nil {
		resp.ErrorHandler(c, err)
	} else {
		resp.Success(c, constant.CodeSuccessUpdate, updateUserRespBodyData{
			Username: user.GetUsername(),
			Name:     user.GetName(),
			Role:     user.GetRole(),
		})
	}
}
